<template>
  <div class="add-search-nav">
    <div class="add-row">
      <el-button
        v-for="(item, index) in TS__Props_AddData"
        v-waves
        :key="index"
        :type="item.type"
        :icon="item.icon"
        @click="item.callback"
      >
        {{ item.content || '添加' }}
      </el-button>
    </div>
    <div class="filter-row">
      <div
        ref="tsFilterButton"
        class="ts-filter-button"
        v-waves
        @click="handleClickFilter"
        slot="reference"
      >
        <svg-icon
          :style="
            filterVisible
              ? 'color: rgba(22, 140, 252, 1)'
              : 'color: rgba(199, 207, 214, 1)'
          "
          :name="'icon_filter_normal'"
        ></svg-icon>
        <span
          :style="
            filterVisible
              ? 'color:rgba(24, 144, 255, 1)'
              : 'color: rgba(68, 68, 68, 1)'
          "
          >过滤</span
        >
      </div>
    </div>
    <transition name="fade">
      <div
        v-if="filterVisible"
        class="ts-filter-popover-content"
        :style="[filterHeight]"
      >
        <div class="ts-filter-popover-content-title">
          <span>过滤</span>
          <i class="el-icon-close" @click="filterVisible = false"></i>
        </div>
        <div class="ts-filter-popover-content-form">
          <el-form
            :model.sync="TS__Props_FilterData.value"
            ref="filterForm"
            label-position="top"
            style="width: 300px; "
            :rules="TS__Props_FilterData.rules"
          >
            <slot name="formItem" />
            <el-form-item
              v-for="(item, index) in TS__Props_FilterData.filterDataItem"
              :key="index"
              :label="item.label"
              :prop="item.prop"
            >
              <!-- 输入框 -->
              <el-input
                v-if="item.type === 'input'"
                v-model="TS__Props_FilterData.value[item.prop]"
                style="width: 100%"
                :disabled="item.disabled"
                :clearable="item.clearable"
                :placeholder="item.placeholder"
                @keyup.enter.native="TS__Props_FilterData.search"
              ></el-input>
              <!-- 下拉选项 -->
              <el-select
                v-else-if="item.type == 'select'"
                v-model="TS__Props_FilterData.value[item.prop]"
                :multiple="item.multiple"
                style="width: 100%"
                :disabled="item.disabled"
                :clearable="item.clearable"
                :placeholder="item.placeholder"
                @keyup.enter.native="TS__Props_FilterData.search"
              >
                <el-option
                  v-for="(optItem, index) in TS__Props_FilterData
                    .filterSelectOption[item.prop]"
                  :key="index"
                  :label="optItem.value"
                  :value="optItem.key"
                ></el-option>
              </el-select>
              <!-- 日期选择 -->
              <el-date-picker
                style="width: 100%"
                v-else-if="dateSelectType.includes(item.type)"
                v-model="TS__Props_FilterData.value[item.prop]"
                :type="item.type"
                :value-format="item.dateFormat || 'yyyy-MM-dd'"
                :disabled="item.disabled"
                :clearable="true"
                :picker-options="item.pickerOptions"
                :placeholder="item.label"
                :start-placeholder="item.startPlaceholder"
                :end-placeholder="item.endPlaceholder"
                @keyup.enter.native="TS__Props_FilterData.search"
              ></el-date-picker>
              <!-- 单选框 -->
              <el-radio-group
                v-else-if="item.type == 'radio'"
                key="radio"
                v-model="TS__Props_FilterData.value[item.prop]"
                @keyup.enter.native="TS__Props_FilterData.search"
              >
                <el-radio
                  v-for="(item, index) in TS__Props_FilterData
                    .filterSelectOption[item.prop]"
                  :label="item.key"
                  :key="index"
                  >{{ item.value }}</el-radio
                >
              </el-radio-group>
              <!-- 多选框 -->
              <el-checkbox-group
                v-else-if="item.type == 'checkbox'"
                key="checkbox"
                v-model="TS__Props_FilterData.value[item.prop]"
                @keyup.enter.native="TS__Props_FilterData.search"
              >
                <el-checkbox
                  v-for="item in TS__Props_FilterData.filterSelectOption[
                    item.prop
                  ]"
                  :label="item.key"
                  :key="item.key"
                  >{{ item.value }}</el-checkbox
                >
              </el-checkbox-group>
            </el-form-item>
          </el-form>
        </div>
        <div class="ts-filter-popover-content-btn">
          <el-button
            v-waves
            class="btn"
            type="primary"
            @click="TS__Props_FilterData.search"
          >
            过滤
          </el-button>
          <el-button v-waves class="btn" @click="TS__Props_FilterData.reset">
            重置
          </el-button>
        </div>
        <div class="ts-filter__arrow"></div>
      </div>
    </transition>
  </div>
</template>
<script lang="ts">
// 具体用法查看官方API:https://github.com/kaorun343/vue-property-decorator
import { Component, Vue, Watch, Prop } from 'vue-property-decorator'

import { parseTimeJS as parseTime } from '@/utils'
import { AppModule } from '@/store/modules/app.ts'
import { Form } from 'element-ui'
// 任意对象接口
interface objKeyValue {
  [propName: string]: any
}
// 单个option接口
export interface OptionItem {
  key: boolean | string
  value: string
}
// 整体option配置接口
interface objSelectOptionKeyValue {
  [propName: string]: OptionItem[] | []
}
// 回调函数接口
interface ICallbackFunc {
  (): void
}
// 单个过滤条件接口
export interface IFilterDateItem {
  // 基础项
  type: string // 表单类型 目前支持input/select/date全家桶/radio/checkbox
  placeholder?: string | '请选择' // placeholder
  label: string // 表单文字
  prop: string // 表单双向绑定的数据
  defaultValue: string | string[] | boolean // 默认值
  disabled?: boolean | false // 是否禁用
  clearable?: boolean | true // 是否清除
  // 额外项

  // 时间
  dateFormat?: string | 'yyyy-MM-dd' // 时间格式
  startPlaceholder?: string | '开始时间' // --
  endPlaceholder?: string | '结束时间' // --
  pickerOptions?: any | undefined
  // 选择框
  multiple?: boolean | false // select是否多选
}
// 整体过滤窗口接口
export interface IFilterDate {
  value: objKeyValue
  filterDataItem: IFilterDateItem[] | []
  filterSelectOption?: objSelectOptionKeyValue
  rules?: any
  search: ICallbackFunc
  reset: ICallbackFunc
}
// 左侧添加等自定义接口
export interface IAddDateItem {
  type: string
  content: string
  icon?: string
  key?: string
  callback?: ICallbackFunc
}
@Component({
  name: 'TsAddSearchNav',
  components: {}
})
export default class extends Vue {
  @Prop({
    default: () => {
      return {
        value: {},
        filterDataItem: [],
        rules: {},
        search: () => {},
        reset: () => {}
      }
    }
  })
  private TS__Props_FilterData!: IFilterDate

  @Prop({
    // default 数组/对象的默认值应当有一个工厂函数返回
    default: () => {
      return []
    }
  })
  private TS__Props_AddData!: IAddDateItem[] | []
  get filterHeight() {
    // app-main 高度减去外层padding，再减去里层padding-top - top + 超出表单部分
    return { height: AppModule.appMainHeight - 48 - 25 - 45 + 'px' }
  }
  private dateSelectType = [
    'year',
    'month',
    'date',
    'dates',
    'week',
    'datetime',
    'datetimerange',
    'daterange',
    'monthrange'
  ]
  // popover visible属性
  private filterVisible = false
  private changeDatePicker(value: string) {
    console.log(value)
  }
  private setDefaultValue() {
    const formData: objKeyValue = { ...this.TS__Props_FilterData.value }
    // 设置默认值
    this.TS__Props_FilterData.filterDataItem.forEach(
      (item: IFilterDateItem, index: any) => {
        if (formData[item.prop] === undefined || formData[item.prop] === null) {
          formData[item.prop] = item.defaultValue
        }
      }
    )
    this.$emit('input', formData)
  }
  mounted() {
    this.setDefaultValue()
  }
  private handleClickFilter() {
    this.filterVisible = !this.filterVisible
  }
  private validate(callback: any) {
    ;(this.$refs['filterForm'] as Form).validate(valid => {
      if (valid) {
        callback(true)
      } else {
        callback(false)
      }
    })
  }
}
</script>
<style lang="scss" scoped>
.add-search-nav {
  display: flex;
  justify-content: space-between;
  position: relative;
  margin-bottom: 25px;
  .filter-row {
    .ts-filter-button {
      padding: 11px 20px;
      height: 36px;
      border-radius: 4px;
      border: 1px solid rgba(220, 223, 230, 1);
      background-color: rgba(255, 255, 255, 1);
      display: flex;
      justify-content: center;
      align-items: center;
      &:hover {
        cursor: pointer;
        background-color: rgba(24, 144, 255, 0.05);
      }
      & > span {
        user-select: none;
        margin-left: 4px;
        font-size: 14px;
        color: rgba(68, 68, 68, 1);
      }
    }
  }
  .ts-filter-popover-content {
    background-color: rgba(255, 255, 255, 1);
    box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.06);
    border: 1px solid rgba(228, 231, 237, 1);
    width: 348px;
    z-index: 3000;
    position: absolute;
    top: 45px;
    right: 0;
    height: 0;
    bottom: 0;
    border-radius: 4px;
    .ts-filter__arrow {
      border-width: 6px;
      filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
      position: absolute;
      display: block;
      width: 0;
      height: 0;
      border-color: transparent;
      border-style: solid;
      top: -6px;
      left: 82%;
      margin-right: 3px;
      border-top-width: 0;
      border-bottom-color: #ebeef5;
      &::after {
        content: ' ';
        border-width: 6px;
        top: 1px;
        margin-left: -6px;
        border-top-width: 0;
        position: absolute;
        display: block;
        width: 0;
        height: 0;
        border-color: transparent;
        border-style: solid;
        border-bottom-color: #fff;
      }
    }
    .ts-filter-popover-content-title {
      border-bottom: 1px solid rgba(235, 238, 245, 1);
      padding: 0 24px;
      height: 55px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      span {
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: rgba(56, 58, 63, 1);
        line-height: 14px;
      }
      i {
        font-size: 16px;
        cursor: pointer;
        &:hover {
          color: rgba(24, 144, 255, 1);
        }
      }
    }
    .ts-filter-popover-content-form {
      overflow-y: scroll;
      max-height: calc(100% - 118px);
      padding: 0 24px;
      ::v-deep .el-form-item {
        margin-bottom: 10px;
        &:last-child {
          margin-bottom: 46px;
        }
      }
      ::v-deep .el-form-item__label {
        font-size: 14px;
        font-family: PingFangSC-Regular, PingFang SC;
        font-weight: 400;
        color: rgba(153, 153, 153, 1);
        line-height: 50px;
        padding: 0;
      }
    }
    .ts-filter-popover-content-btn {
      position: absolute;
      bottom: 0;
      height: 63px;
      padding: 0 24px;
      width: 100%;
      border-top: 1px solid rgba(235, 238, 245, 1);
      display: flex;
      align-items: center;
      justify-content: flex-end;
      .btn {
        width: 96px;
        &:first-child {
          margin-right: 12px;
        }
      }
    }
  }
}
</style>
